Goal of the Analysis: The objective of our analysis is to try to understand the structure of terrorist organizations trying to find the 3 main macro structures represented in the image below:

Type of Terrorist Network

It is important to note that these organizational models are simplifications, and terrorist networks can exhibit complex and variable forms and structures.

After understanding the structure of our network we want to analyze how the structure changes trying to remove key figures of the organization.

Network Loading

Some useful library for our analysis:

library(tidyverse)
library(igraph)
library(sand)

Let’s start to import all the dataset:

# Load the data 
data<-readLines("TerroristRel.edges")

# Split the node in each sub-list contain in "data"
edges <- strsplit(data, ",")

# Create a dataframe
edg = data.frame(edges)
edg = t(edg)

# Let's transform it into a tibble
edg = as.tibble(edg)
edg
## # A tibble: 8,592 × 2
##    V1    V2   
##    <chr> <chr>
##  1 1     2    
##  2 1     3    
##  3 1     4    
##  4 1     5    
##  5 1     6    
##  6 1     7    
##  7 1     8    
##  8 1     9    
##  9 1     10   
## 10 1     11   
## # … with 8,582 more rows

Newtwork Description

# Plot our graph:
set.seed(104)
full_terr = graph_from_data_frame(edg, directed = FALSE)
full_terr
## IGRAPH d236d33 UN-- 881 8592 -- 
## + attr: name (v/c)
## + edges from d236d33 (vertex names):
##  [1] 1 --2  1 --3  1 --4  1 --5  1 --6  1 --7  1 --8  1 --9  1 --10 1 --11
## [11] 1 --12 1 --13 1 --14 1 --15 1 --16 1 --17 18--19 18--20 18--21 18--22
## [21] 18--23 18--24 25--21 25--26 25--27 25--28 25--29 25--30 31--32 31--33
## [31] 31--34 31--20 31--27 31--35 31--36 31--37 31--38 31--39 40--22 40--28
## [41] 40--36 40--41 40--42 40--43 44--24 44--30 44--38 44--43 44--45 44--46
## [51] 47--19 47--26 47--35 47--41 47--45 47--48 49--23 49--29 49--37 49--42
## [61] 49--46 49--48 50--51 50--52 50--53 50--54 50--55 50--56 50--57 50--58
## [71] 50--59 50--60 50--61 62--63 62--64 62--65 62--66 62--67 62--68 62--69
## + ... omitted several edges
plot(full_terr, vertex.label = NA, edge.label = NA,
     edge.color = "black", vertex.size = 4, 
     main = "Terrorist Network", 
     layout = layout.fruchterman.reingold)

As we can see from the numerical representation of the graph we can observe that we have:
- 881 nodes that represent each terrorist in our network.
- 8592 edges that are the connection between terrorists.

We can also observe that seems to be some group of terrorist that have no edges that link them to the main central network; these autonomous components of the graph could represent newborn star hubs, not interconnected with the main network of terrorists.

Check features of the network

Since in the description of the dataset there is no information about the main characteristic of our graph, we want to start to check if it is weighted or not.

# Let's built the column that compute the weight of each edges:
w = edg %>% transmute(A = pmin(V1,V2), B = pmax(V1,V2)) %>% distinct() %>% group_by(A,B) %>% summarize(weight = n())
w
## # A tibble: 8,592 × 3
## # Groups:   A [838]
##    A     B     weight
##    <chr> <chr>  <int>
##  1 1     10         1
##  2 1     11         1
##  3 1     12         1
##  4 1     13         1
##  5 1     14         1
##  6 1     15         1
##  7 1     16         1
##  8 1     17         1
##  9 1     2          1
## 10 1     3          1
## # … with 8,582 more rows
# Check if all the weights are equal to 1:
are_all_ones = w %>% 
  pull(weight) %>%
  all(.==1)
are_all_ones
## [1] TRUE

As we can see from the tibble above we have all the weights equal to 1, so our graph is unweighted.

Check if our graph is connected:

is.connected(full_terr)
## [1] FALSE

This result confirms that exist in the network some independent terrorist cells.

Degree Analysis:

The degree of a vertex in a graph refers to the number of edges connected to that vertex. It represents the number of neighbors or adjacent vertices that are directly connected to a given vertex. In our case the degree of a vertex can provide insights into the connectivity and potential influence of individuals within the terrorist network.

siu = summary(degree(full_terr))
siu
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1.00   12.00   21.00   19.51   28.00   36.00

From the summary above we can observe the Minimum number of degree, the mean value and also the maximum.

Let’s now plot an histogram of the degree and the degree distribution:

media = siu[4]
mediano = siu[3]

fd = degree_distribution(full_terr) # Degree distribution
names(fd) = 0:max(degree(full_terr))
d = seq_along(fd)

par(mfrow = c(1,2))
V(full_terr)$degree <- degree(full_terr)
uni_all <- seq( min(V(full_terr)$degree), max(V(full_terr)$degree)+1)
hist(degree(full_terr), breaks =36, col = hcl.colors(length(uni_all), rev = T,palette = "inferno"), main = "Histogram of Degree", xlab = "Degree")
abline(v = media, lwd=2, col ="red")
abline(v = mediano, lwd=2, col ="blue")
plot(log(d), log(fd), col = hcl.colors(length(uni_all), rev = T,palette = "inferno"),pch=19, main = "Log Scale Representation", xlab = "Log(Degree)", ylab = "Log(Frequency")

The fact that median is higher than the value of the mean suggest that most of the terrorists have lots of connections meaning that they should be central or influential terrorists in the network. Also graphically we can observe the presence of this relevant terrorists (represented with the color purple), that have high frequency in both graphs.

Another interesting fact that we can observe from the histogram is that before the maximum numbers of degrees there are some zero frequencies that may identify the terrorists with max degree as leaders of the whole network.

let’s visualize the disposition of the degree in our network:

set.seed(104)
V(full_terr)$degree <- degree(full_terr)
uni_all <- seq( min(V(full_terr)$degree), max(V(full_terr)$degree)+1)
colors <- data.frame( color = hcl.colors(length(uni_all), rev = T,palette = "inferno"),
                      levels = uni_all)

# Use match to get the index of right color, matching on levels
V(full_terr)$color <- colors$color[match(V(full_terr)$degree, colors$levels)]

plot(full_terr,vertex.label=NA,vertex.size = 4, layout=layout.fruchterman.reingold)

Observing the position of the nodes and the relative degrees we can assume the presence of individuals with specific roles that we will try to analyze in details later using other metrics.

a.nn.deg.terr <- knn(full_terr,V(full_terr))$knn
plot(degree(full_terr), a.nn.deg.terr,
col="darkorange", xlab=c("Vertex Degree"), ylab=c("Average Neighbor Degree"), pch= 20)
abline(lm(a.nn.deg.terr~(degree(full_terr))), col ="slategray")

We can observe a linear increasing trend that means that in general more important terrorists are linked with other important terrorists. 

Transitivity

Transitivity measures the probability that the neighbors of a node are also connected to each other.

transitivity(full_terr)
## [1] 0.5333777

A value of \(0.5\) means that, on average, half of the neighbors of a node are connected to each other. In the context of a graph of connections between terrorists, it could indicate the presence of subgroups of terrorists that are closely connected to each other, potentially forming networks of support, collaboration, or coordination within the terrorist organization.

Graph decomposition

Let’s now start to decompose our network into complete subgraph in order to analyze each single cell:

component_list = decompose.graph(full_terr, mode = "weak")
component_list
## [[1]]
## IGRAPH 45abdc1 UN-- 687 6884 -- 
## + attr: name (v/c), degree (v/n), color (v/c)
## + edges from 45abdc1 (vertex names):
##  [1] 1 --2  1 --3  1 --4  1 --5  1 --6  1 --7  1 --8  1 --9  1 --10 1 --11
## [11] 1 --12 1 --13 1 --14 1 --15 1 --16 1 --17 18--19 18--20 18--21 18--22
## [21] 18--23 18--24 25--21 25--26 25--27 25--28 25--29 25--30 31--32 31--33
## [31] 31--34 31--20 31--27 31--35 31--36 31--37 31--38 31--39 40--22 40--28
## [41] 40--36 40--41 40--42 40--43 44--24 44--30 44--38 44--43 44--45 44--46
## [51] 47--19 47--26 47--35 47--41 47--45 47--48 49--23 49--29 49--37 49--42
## [61] 49--46 49--48 50--51 50--52 50--53 50--54 50--55 50--56 50--57 50--58
## [71] 50--59 50--60 50--61 62--63 62--64 62--65 62--66 62--67 62--68 62--69
## + ... omitted several edges
## 
## [[2]]
## IGRAPH c8431c2 UN-- 26 129 -- 
## + attr: name (v/c), degree (v/n), color (v/c)
## + edges from c8431c2 (vertex names):
##  [1] 89 --96  89 --100 96 --100 89 --105 96 --105 100--105 89 --110 96 --110
##  [9] 100--110 105--110 100--101 110--101 89 --90  100--90  101--90  100--102
## [17] 105--102 101--102 90 --102 100--103 101--103 90 --103 102--103 100--104
## [25] 101--104 90 --104 102--104 103--104 96 --97  100--97  101--97  90 --97 
## [33] 102--97  103--97  104--97  89 --93  90 --93  103--93  105--108 102--108
## [41] 103--108 93 --108 110--111 101--111 103--111 93 --111 108--111 103--751
## [49] 104--751 93 --751 108--751 111--751 89 --95  96 --95  90 --95  97 --95 
## [57] 93 --95  96 --98  105--98  102--98  97 --98  108--98  95 --98  96 --99 
## + ... omitted several edges
## 
## [[3]]
## IGRAPH 5029115 UN-- 110 1360 -- 
## + attr: name (v/c), degree (v/n), color (v/c)
## + edges from 5029115 (vertex names):
##  [1] 443--456 443--471 456--471 443--482 456--482 471--482 443--493 456--493
##  [9] 471--493 482--493 443--505 456--505 471--505 482--505 493--505 443--514
## [17] 456--514 471--514 482--514 493--514 505--514 443--522 456--522 471--522
## [25] 482--522 493--522 505--522 514--522 443--528 456--528 471--528 482--528
## [33] 493--528 505--528 514--528 522--528 443--532 456--532 471--532 482--532
## [41] 493--532 505--532 514--532 522--532 528--532 443--537 456--537 471--537
## [49] 482--537 493--537 505--537 514--537 522--537 528--537 532--537 443--544
## [57] 456--544 471--544 482--544 493--544 505--544 514--544 522--544 528--544
## + ... omitted several edges
## 
## [[4]]
## IGRAPH facb77f UN-- 3 3 -- 
## + attr: name (v/c), degree (v/n), color (v/c)
## + edges from facb77f (vertex names):
## [1] 589--591 589--590 591--590
## 
## [[5]]
## IGRAPH ab09613 UN-- 3 3 -- 
## + attr: name (v/c), degree (v/n), color (v/c)
## + edges from ab09613 (vertex names):
## [1] 592--594 592--593 594--593
## 
## [[6]]
## IGRAPH d284da2 UN-- 3 3 -- 
## + attr: name (v/c), degree (v/n), color (v/c)
## + edges from d284da2 (vertex names):
## [1] 620--622 620--621 622--621
## 
## [[7]]
## IGRAPH 286f053 UN-- 3 3 -- 
## + attr: name (v/c), degree (v/n), color (v/c)
## + edges from 286f053 (vertex names):
## [1] 722--724 722--723 724--723
## 
## [[8]]
## IGRAPH 406d883 UN-- 6 12 -- 
## + attr: name (v/c), degree (v/n), color (v/c)
## + edges from 406d883 (vertex names):
##  [1] 725--728 725--730 728--730 725--726 728--726 728--729 730--729 726--729
##  [9] 725--727 730--727 726--727 729--727
## 
## [[9]]
## IGRAPH 760043c UN-- 3 3 -- 
## + attr: name (v/c), degree (v/n), color (v/c)
## + edges from 760043c (vertex names):
## [1] 731--733 731--732 733--732
## 
## [[10]]
## IGRAPH 4405e68 UN-- 28 168 -- 
## + attr: name (v/c), degree (v/n), color (v/c)
## + edges from 4405e68 (vertex names):
##  [1] 814--821 814--827 821--827 814--832 821--832 827--832 814--836 821--836
##  [9] 827--836 832--836 814--839 821--839 827--839 832--839 836--839 814--841
## [17] 821--841 827--841 832--841 836--841 839--841 814--815 821--815 821--822
## [25] 836--822 815--822 821--823 832--823 815--823 822--823 821--824 841--824
## [33] 815--824 822--824 823--824 821--825 827--825 815--825 822--825 823--825
## [41] 824--825 821--826 839--826 815--826 822--826 823--826 824--826 825--826
## [49] 814--816 827--816 815--816 825--816 827--828 836--828 822--828 825--828
## [57] 816--828 827--829 832--829 823--829 825--829 816--829 828--829 827--830
## + ... omitted several edges
## 
## [[11]]
## IGRAPH 2214fcc UN-- 9 24 -- 
## + attr: name (v/c), degree (v/n), color (v/c)
## + edges from 2214fcc (vertex names):
##  [1] 857--861 857--864 861--864 857--860 864--865 860--865 861--863 860--863
##  [9] 865--863 857--858 861--858 860--858 863--858 857--859 864--859 860--859
## [17] 865--859 858--859 861--862 864--862 865--862 863--862 858--862 859--862
plot(component_list[[1]], vertex.label = NA, vertex.size = 3) 

plot(component_list[[2]], vertex.label = NA, vertex.size = 3)

plot(component_list[[3]], vertex.label = NA, vertex.size = 3) 

plot(component_list[[4]], vertex.label = NA, vertex.size = 3) 

plot(component_list[[10]], vertex.label = NA, vertex.size = 3)

Looking at the plot of all the components we can consider in our analysis just two more relevant ones, avoiding the analysis of the trivial cells.

Hence, the only thing that we can do with the other small components is to check if they are stars or hubs or not:

star_hub2 = component_list[[2]]

set.seed(104)
V(star_hub2)$degree <- degree(star_hub2)
hub_all <- seq( min(V(star_hub2)$degree), max(V(star_hub2)$degree)+1)
colors <- data.frame( color = hcl.colors(length(hub_all), rev = T,palette = "inferno"),
                      levels = hub_all)
# Use match to get the index of right color, matching on levels
V(star_hub2)$color <- colors$color[match(V(star_hub2)$degree, colors$levels)]

plot(star_hub2,vertex.label=NA,vertex.size = 4, layout=layout.fruchterman.reingold)

We can confirm that the the second component is a perfect representation of a star hub, in which we can see a vertical organization (with a main central node).

Let’s now the tenth component:

star_hub10 = component_list[[10]]

set.seed(104)
V(star_hub10)$degree <- degree(star_hub10)
hub10_all <- seq( min(V(star_hub10)$degree), max(V(star_hub10)$degree)+1)
colors <- data.frame( color = hcl.colors(length(hub10_all), rev = T,palette = "inferno"),
                      levels = hub10_all)
# Use match to get the index of right color, matching on levels
V(star_hub10)$color <- colors$color[match(V(star_hub10)$degree, colors$levels)]

plot(star_hub10,vertex.label=NA,vertex.size = 4, layout=layout.fruchterman.reingold)

In this case the component is not representing a star hub, due to the fact that all the nodes have the same degree, so this structure can be reconducted to the all-channel type of organization.

degree(star_hub10)
## 814 821 827 832 836 839 841 815 822 823 824 825 826 816 828 829 830 831 817 833 
##  12  12  12  12  12  12  12  12  12  12  12  12  12  12  12  12  12  12  12  12 
## 834 835 820 838 840 819 837 818 
##  12  12  12  12  12  12  12  12
is.connected(star_hub10)
## [1] TRUE

Falcon

Falcon represents the second biggest subgraph of our initial network and it is composed by 110 nodes and 1360 edges.
From the plot above falcon has typical structure of an “All Channels”.

falcon = component_list[[3]]

d_falcon = degree(falcon)
mean_dfalcon = mean(d_falcon)
median_dfalcon = median(d_falcon)
V(falcon)$degree <- degree(falcon)
uni_falcon <- seq( min(V(falcon)$degree), max(V(falcon)$degree)+1)
hist(d_falcon, breaks =10, col = hcl.colors(length(uni_falcon), rev = T,palette = "orange"), main= "Histogram of Degree: Falcon", xlab = "Degree")
abline(v = mean_dfalcon, lwd=2, col ="red")
abline(v = median_dfalcon, lwd=2, col ="blue")

summary(degree(falcon))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    8.00   25.00   26.00   24.73   27.00   30.00

The lower value of degree is 8 and we can also notice from the quantiles that the 75% of falcon’s nodes have 25 or more degrees.

set.seed(69)
plot(falcon, vertex.label = NA,vertex.size = 4, layout= layout.fruchterman.reingold)  #

Why “Falcon”?

Grafone

Grafone represents the biggest subgraph of our initial network and it is composed by 687 nodes and 6884 edges

grafone = component_list[[1]]
plot(grafone, layout= layout.kamada.kawai, vertex.label = NA, vertex.size = 3)

d_grafone = degree(grafone)

mean_dgrafone = mean(d_grafone)
median_dgrafone = median(d_grafone)

hist(d_grafone, breaks =36, col = hcl.colors(length(uni_all), rev = T,palette = "greens"), main = "Histogram of Degree: Grafone", xlab = "Degree")
abline(v = mean_dgrafone, lwd=2, col ="red")
abline(v = median_dgrafone, lwd=2, col ="blue")

The histogram above is very similar to the histogram of the whole network, in fact it has a very close allocation of the value of degree.  Thanks to this similarity, we will focus our further analysis on this component, in which we would like the find out the organization of this big terrorist cell.

In order to analyze the centrality of some important node in this component we would like to focus on the:

- Betweenness centrality
- Eigen centrality

Betweenness centrality

Betweenness centrality measures the extent to which a node acts as a bridge or intermediary between other nodes in the graph.
In the context of a terrorist graph, high betweenness centrality for a node suggests that it serves as a critical link or connector between different individuals or groups within the network. Such nodes can play important roles in the transmission of information, coordination of activities, or control over the flow of resources. They may act as influential figures, brokers, or facilitators in the network.
These subjects are commonly called linkers.

\[ c_{B}(v) = \sum_{s\neq t\neq v \in V} \frac{\sigma(s,t|v)}{\sigma(s,t)} \]

\(\sigma(s,t|v)\) : number of the shortest path between \(s\) and \(t\) that pass through \(v\).
\(\sigma(s,t)\) :number of the shortest path between \(s\) and \(t\).

b_grafone = betweenness(grafone,directed = FALSE)

hist(b_grafone,breaks = 100, col = hcl.colors(10, rev = T,palette = "reds"), main = "Histogram of Betweenness: Grafone", xlab = "Betweenness")

summary(b_grafone)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##     0.00    33.00    54.67  1766.14   880.32 87384.14

We can observe that the majority of the nodes has low value of betweenness, but the distribution shows the presence of heavy tail in which we can observe extremely high value of betweenness.

We can have a look to some of this extreme values, for simplicity we can consider the first 30 nodes according to the highest values of betweenness.

linkers <- names(sort(b_grafone, decreasing = TRUE)[1:30])
# Create color vector
colors <- rep("white", vcount(grafone))  # Initialize all points with the same color
colors[V(grafone)$name %in% linkers] <- "red"  # Assign different color to top nodes

# Plot the graph with different colors
set.seed(104)
plot(grafone, vertex.color = colors, vertex.label = NA,vertex.size = 4, layout= layout.kamada.kawai)  # Modify vertex.label to show node labels if needed

These terrorists seem to have a key role in the coordination between groups, for this reason we can associate them to the figure of linkers. By comparing them to the ones in the previous graph we can see that the nodes with high degree values are not the ones with high betweenness.

Linkers’ utily

In this section we want to see the importance of linkers and how their removal from the network can change the general structure.

TEST = delete.vertices(grafone,linkers)
plot(TEST, vertex.label =NA, vertex.size =4, layout = layout.kamada.kawai)

From the graph above we can see that removing the linkers you get additional sub-components, partly independent and with similar structures to those observed previously.
These subjects may be key points for the expansion of the terrorist network.

Eigen Centrality

We can now introduce a new metric to asses the importance of nodes: Eigen centrality is a measure used in network analysis to quantify the importance or centrality of a node within a network. It is based on the concept of eigen from linear algebra. In simple terms, eigen centrality assigns a score to each node in a network based on its connections to other highly central nodes.

a= eigen_centrality(grafone)
hist(a$vector, col ="green4",main = "Eigen Centrality", xlab = "eigen centrality")

Let’s now show in the representation of grafone the nodes with the highest values of eigen centrality:

Hegelc <- names(sort(a$vector, decreasing = TRUE)[1:17])
linkers <- names(sort(b_grafone, decreasing = TRUE)[1:30])
maxdegree = names(sort(d_grafone, decreasing = TRUE)[1:17])
# Create color vector
colors <- rep("white", vcount(grafone))  # Initialize all points with the same color
colors[V(grafone)$name %in% Hegelc] = "green" # Assign different color to top nodes
colors[V(grafone)$name %in% linkers] <- "red"
shapes = rep("circle",vcount(grafone))
shapes[V(grafone)$name %in% maxdegree] = "square"

# Plot the graph with different colors
set.seed(104)
plot(grafone, vertex.color = colors, vertex.shape=shapes, vertex.label = NA,vertex.size = 4, layout= layout.kamada.kawai)  # Modify vertex.label to show node labels if needed

As we can see from graph above the nodes with high eigen centrality values are grouped near to the “All Channels” structures, allowing these structures to join through the linkers to more complex terrorist organizations.
These nodes will be called propagators in later analysis.

Now we can try detect the propagators of the others “All Channels” structures by removing the linkers.

component_list_TEST = decompose.graph(TEST, mode = "weak")
sub_grafone = component_list_TEST[[1]]
simil_falcon = component_list_TEST[[3]]
plot(sub_grafone, vertex.label =NA, vertex.size =4, layout = layout.kamada.kawai)

plot(simil_falcon, vertex.label =NA, vertex.size =4, layout = layout.kamada.kawai)

These above are the two biggest component after the removal of linkers.

Let’s see where the new propagators are located in both these new structures:

a_sub_grafone = eigen_centrality(sub_grafone)
b_sub_grafone = betweenness(sub_grafone)
d_sub_grafone = degree(sub_grafone)

Hegelc_sub <- names(sort(a_sub_grafone$vector, decreasing = TRUE)[1:20])
linkers_sub <- names(sort(b_sub_grafone, decreasing = TRUE)[1:10])
maxdegree_sub = names(sort(d_sub_grafone, decreasing = TRUE)[1:10])
# Create color vector
colors <- rep("white", vcount(sub_grafone))  # Initialize all points with the same color
colors[V(sub_grafone)$name %in% Hegelc_sub] = "Green" # Assign different color to top nodes
#colors[V(sub_grafone)$name %in% linkers_sub] <- "red"
shapes = rep("circle",vcount(sub_grafone))
shapes[V(sub_grafone)$name %in% maxdegree_sub] = "square"

# Plot the graph with different colors
set.seed(104)
plot(sub_grafone, vertex.color = colors, vertex.shape=shapes, vertex.label = NA,vertex.size = 4, layout= layout.kamada.kawai)  # Modify vertex.label to show node labels if needed

As we expect, the new most important propagators are located on the boundaries of the main “All Channels”. Please note: the result are not so clear since after removing linkers other nodes are represented closer to the “All Channels” structure.

Let’s now see how the propagators are located in the other sub component.

a_simil_falcon = eigen_centrality(simil_falcon)
b_simil_falcon = betweenness(simil_falcon)
d_simil_falcon = degree(simil_falcon)

Hegelc_sfalcon <- names(sort(a_simil_falcon$vector, decreasing = TRUE)[1:20])
linkers_sfalcon <- names(sort(b_simil_falcon, decreasing = TRUE)[1:10])
maxdegree_sfalcon = names(sort(d_simil_falcon, decreasing = TRUE)[1:10])
# Create color vector
colors <- rep("white", vcount(simil_falcon))  # Initialize all points with the same color
colors[V(simil_falcon)$name %in% Hegelc_sfalcon] = "Green" # Assign different color to top nodes
#colors[V(simil_falcon)$name %in% linkers_sfalcon] <- "red"
shapes = rep("circle",vcount(simil_falcon))
shapes[V(simil_falcon)$name %in% maxdegree_sfalcon] = "square"

# Plot the graph with different colors
set.seed(104)
plot(simil_falcon, vertex.color = colors, vertex.shape=shapes, vertex.label = NA,vertex.size = 4, layout= layout.kamada.kawai)  # Modify vertex.label to show node labels if needed

Also in this plot, even if the removal of linkers have changed a bit the representation, all the propagators are close to the ones found previously.

COMPARISON We can now visualize the position of the highest value of Eigen Centrality on falcon’s plot:

a= eigen_centrality(falcon)

HegelcFalcon <- names(sort(a$vector, decreasing = TRUE)[1:10])
maxdegree = names(sort(d_falcon, decreasing = TRUE)[1:10])
# Create color vector
colors <- rep("white", vcount(falcon))  # Initialize all points with the same color
colors[V(falcon)$name %in% HegelcFalcon] = "green"
shapes = rep("circle",vcount(falcon))
shapes[V(falcon)$name %in% maxdegree] = "square"

# Plot the graph with different colors
set.seed(69)
plot(falcon, main = "Falcon", vertex.color = colors, vertex.shape=shapes, vertex.label = NA,vertex.size = 4, layout= layout.fruchterman.reingold)  # Modify vertex.label to show node labels if needed

We can see that the two plots are very similar, so since we know that “simil falcon” is linked with the main terrorist organization thanks to some linkers, we can assume that in the future falcon may follow the same evolution becoming part of a bigger network.

Stochastic Block Model

The Stochastic Block Model (SBM) is a generative probabilistic model for networks. It assumes that the network is formed by multiple blocks or communities, where nodes within the same block have a higher probability of being connected to each other compared to nodes in different blocks. The SBM provides a framework for modeling and understanding the community structure and connectivity patterns in complex networks.

#stochastic block model
am_grafone <- as_adjacency_matrix(grafone, sparse = FALSE)
gm_grafone <- sbm::estimateSimpleSBM(am_grafone , model="poisson", estimOptions = list(plot = FALSE))
plot(gm_grafone)

The matrix above represents connections between nodes: nodes belonging to the same class tend to have a greater number of connections with nodes belonging to the same class.
The number of classes used to represent this matrix is equal to 15, value that maximizes the ICL (Integrated Completed Likelihood).  Among these 15 classes we can see that 3 of them a quite big dimension and we can assume that these three classes represent the main “All Channel” that we have observed before.
Check it graphically:

membri_2 = which(gm_grafone$memberships==2)
vertices_2 <- V(grafone)[membri_2]
membri_5 = which(gm_grafone$memberships==5)
vertices_5 <- V(grafone)[membri_5]
membri_6 = which(gm_grafone$memberships==6)
vertices_6 <- V(grafone)[membri_6]

colors <- rep("white", vcount(grafone))  # Initialize all points with the same color
colors[V(grafone)[membri_2]] = "green" # Assign different color to top nodes

colors[V(grafone)[membri_5]] = "red" # Assign different color to top nodes

colors[V(grafone)[membri_6]] = "blue" # Assign different color to top nodes

# Plot the graph with different colors
set.seed(104)
plot(grafone, vertex.color = colors, vertex.label = NA,vertex.size = 4, layout= layout.kamada.kawai)

Clustering

Fast_greedy

The algorithm works by iteratively merging or splitting communities to optimize a modularity score. Modularity measures the quality of the division of a graph into communities, with higher modularity indicating a better division.

clstr = cluster_fast_greedy(grafone)
sizes(clstr)
## Community sizes
##   1   2   3   4   5   6   7   8 
## 148 120  33 120  86  99  47  34

We can observe three high values of the size, suggesting the presence of three main “All Channels” structures.

hist(clstr$modularity,main="Modularity Histogram",col = "olivedrab",breaks=8, xlab="Modularity")
summary(clstr$modularity)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## -0.001781  0.123845  0.309350  0.317133  0.507422  0.737868
abline(v=mean(clstr$modularity),col="lightcoral", lwd =3)
abline(v=median(clstr$modularity),col="mediumturquoise", lwd=3)

The mean value \(0.32\) represents the average modularity across all communities in the graph. It suggests an overall tendency for the nodes within communities to be more densely connected compared to the connections between communities.

plot(clstr,grafone,vertex.label = NA,vertex.size = 3,layout = layout.kamada.kawai)

From the plot above we can see clearly the three main “All Channels” but we are not able to clearly distinguish the other two common structures.

Cluster Edge Betweenness

We can also compute the clusterization based on edge betweenness centrality due to the fact that in previous analysis we have find out the importance of the linkers in the terrorists’ organization.
Edge betweenness centrality measures the number of times a particular edge is included in the shortest path between all pairs of nodes in the network.

#Cluster edge betweenness
fastlife = cluster_edge_betweenness(grafone)
sizes(fastlife)
## Community sizes
##   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16 
## 127  34  42 113  32  35  38  33 142  44   7  17  13   2   7   1
plot(fastlife,grafone,vertex.label = NA,vertex.size = 3,layout = layout.kamada.kawai)

With this different type of clusterization we have obtained 16 different communities; This result shows in a better way the three different typologies of terroristic organizations without loosing information about the “All Channels” that we found in the previous analysis.

Conclusion

Thanks to this analysis we are able to understand the process of formation of large terrorist networks.
The first terrorist cells that are formed are composed of 3 individuals, over time these cells tend to expand but acquiring a hierarchy of command in the “Hub” phase. Continuing their expansion then reach the stage of “All Channels” in which they return to have an equal power within the terrorist cell and creating a large number of connections between members who belong to it.
Once established as “All Channels” through connections with linkers these structures can become part of large Terrorist Networks.